use std::time::Duration;
use std::any::Any;
use async_trait::async_trait;
use tracing::{info, debug, warn, error};

use protoactor_rs::{
    Actor, ActorContext, ActorError, PID, Props, ActorSystem, 
    logging, 
};

// 定义一个简单的消息
#[derive(Debug, Clone)]
struct Message {
    id: u32,
    content: String,
}

// 定义一个简单的Actor
struct JsonLogActor {
    name: String,
}

#[async_trait]
impl Actor for JsonLogActor {
    type Context = protoactor_rs::actor::DefaultActorContext;
    
    async fn started(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        info!(actor = self.name, event = "startup", "Actor已启动");
        Ok(())
    }
    
    async fn stopping(&self, _ctx: &mut Self::Context) -> Result<(), ActorError> {
        info!(actor = self.name, event = "shutdown", "Actor准备停止");
        Ok(())
    }
    
    async fn receive(&self, ctx: &mut Self::Context, msg: Box<dyn Any + Send>) -> Result<(), ActorError> {
        if let Ok(message) = msg.downcast::<Message>() {
            // 记录结构化日志，这在JSON格式中会体现为嵌套结构
            info!(
                actor = self.name,
                event = "message_received",
                message_type = "Message",
                message_id = message.id,
                message_content = message.content,
                "收到消息"
            );
            
            // 模拟处理
            if message.id % 2 == 0 {
                debug!(
                    actor = self.name, 
                    message_id = message.id,
                    "处理偶数ID消息"
                );
            } else {
                debug!(
                    actor = self.name, 
                    message_id = message.id,
                    "处理奇数ID消息"
                );
            }
            
            // 模拟错误
            if message.id > 5 {
                warn!(
                    actor = self.name,
                    message_id = message.id,
                    reason = "ID超过阈值",
                    "消息处理告警"
                );
            }
            
            // 响应发送者
            ctx.respond(format!("已处理消息: {}", message.id));
        } else {
            error!(
                actor = self.name,
                event = "message_error",
                error_type = "unknown_message",
                "收到未知类型消息"
            );
        }
        
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 显示功能说明
    println!("此示例需要使用json-logging特性编译才能展示JSON日志效果");
    println!("编译命令: cargo run --example json_logging_example --features json-logging");
    println!();
    
    // 初始化日志系统
    #[cfg(feature = "json-logging")]
    {
        // 使用JSON日志格式
        logging::init_json_logger(Some("json_logging_example=info,protoactor_rs=debug"))?;
        println!("已启用JSON格式日志输出");
    }
    
    #[cfg(not(feature = "json-logging"))]
    {
        // 使用标准日志格式
        logging::init_global_logger(
            Some(tracing::Level::DEBUG),
            Some("json_logging_example=info,protoactor_rs=debug"),
        )?;
        println!("使用标准日志格式（未启用json-logging特性）");
    }
    
    // 创建Actor系统
    let system = ActorSystem::new()?;
    
    // 创建多个Actor
    let actor_names = vec!["数据处理", "用户服务", "通知中心"];
    let mut pids = Vec::new();
    
    for (i, name) in actor_names.iter().enumerate() {
        // 为每个Actor创建一个独立的名称
        let name_owned = name.to_string();
        let props = Props::from_producer(move || {
            let name_clone = name_owned.clone(); // 在闭包内克隆
            JsonLogActor { 
                name: name_clone 
            }
        });
        
        let pid = system.spawn::<JsonLogActor>(props).await?;
        pids.push(pid);
        
        // 使用to_string()避免类型问题
        info!(
            actor_system = "main",
            actor_index = i.to_string(),
            actor_name = name,
            "创建Actor"
        );
    }
    
    // 发送多条消息
    for i in 0..8 {
        let pid_index = i % pids.len();
        let message = Message {
            id: i as u32,  // 将usize转换为u32
            content: format!("这是第{}条消息", i),
        };
        
        system.send(&pids[pid_index], message).await?;
    }
    
    // 等待消息处理
    tokio::time::sleep(Duration::from_millis(500)).await;
    
    // 停止所有Actor
    for pid in &pids {
        system.stop(pid).await?;
    }
    
    // 等待Actor停止
    tokio::time::sleep(Duration::from_millis(100)).await;
    
    info!(
        actor_system = "main",
        event = "shutdown",
        "示例执行完成"
    );
    
    Ok(())
} 